<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <title></title>
  <style type="text/css">
    * {
      margin: 0;
      padding: 0;
    }

    ul,
    ol,
    li {
      list-style: none;
    }

    .calendar {
      width: 300px;
      height: 220px;
      border: 1px solid #000;
      margin: 200px auto 0;
    }

    .title {
      display: flex;
      justify-content: space-around;
      align-items: center;
      text-align: center;
      font-size: 12px;
    }

    .year {
      display: flex;
      flex-direction: column;
      margin: 0 40px;
    }

    #week {
      display: flex;
      border-top: 1px solid #000;
      border-bottom: 1px solid #000;
    }

    #week li {
      flex: 1;
      text-align: center;
    }

    #date {
      margin-top: 5px;
    }

    #date li {
      display: inline-block;
      width: 40px;
      height: 22px;
      text-align: center;
      line-height: 22px;
      border: 1px solid #fff;
      border-radius: 50%;
      cursor: pointer;
    }

    #date li.current {
      color: #fff;
      background-color: skyblue;
    }

    #date li.hover {
      border-color: red;
    }

    #prev,
    #next {
      cursor: pointer;
    }
  </style>
</head>

<body>
  <div class="calendar">
    <div class="title">
      <span id="prev">&lt;上一月</span>
      <div class="year">
        <span id="year">2022</span>
        <span id="month">4月</span>
      </div>
      <span id="next">下一月&gt;</span>
    </div>
    <!-- 用ul做日历 -->
    <ul id="week">
      <li>日</li>
      <li>一</li>
      <li>二</li>
      <li>三</li>
      <li>四</li>
      <li>五</li>
      <li>六</li>
    </ul>
    <ul id="date">
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li></li>
      <li>1</li>
      <li class="current">2</li>
      <li>3</li>
      <li>4</li>
      <li>5</li>
      <li>6</li>
      <li>7</li>
      <li>8</li>
      <li>9</li>
      <li>10</li>
      <li>11</li>
      <li>12</li>
      <li>13</li>
      <li>14</li>
      <li>15</li>
      <li>16</li>
      <li>17</li>
      <li>18</li>
      <li>19</li>
      <li>20</li>
      <li>21</li>
      <li>22</li>
      <li>23</li>
      <li>24</li>
      <li>25</li>
      <li>26</li>
      <li>27</li>
      <li>28</li>
      <li>29</li>
      <li>30</li>
    </ul>
  </div>
</body>

<script type="text/javascript">
  // 日期对象
  let date = new Date();
  // console.log(date); // Sat Apr 09 2022 12:30:22 GMT+0800 (中国标准时间)
  // 获取当前时间点的年份
  const currentYear = date.getFullYear(); // Number 2022
  // 获取当前时间点的月份
  const currentMonth = date.getMonth() + 1; // Number 4

  // 点击切换月份的事件
  document.querySelector('#prev').addEventListener('click', () => {
    date.setMonth(date.getMonth() - 1);
    addDate();
  });

  document.querySelector('#next').addEventListener('click', () => {
    date.setMonth(date.getMonth() + 1);
    addDate();
  });

  addDate();

  function addDate() {
    let cYear = date.getFullYear();
    let cMonth = date.getMonth() + 1; // 4
    let cDay = date.getDate();
    // 写入年月
    document.querySelector('#year').innerHTML = cYear;
    document.querySelector('#month').innerHTML = cMonth + '月';

    // 获取当前月份的天数 getMonth() + 1
    // 注意：首次传入cMonth的值为4，原本获取的是5月份的天数。但是由于最后一个参数设置为0，结果就是前一个月的最后一天
    // getDate() 正常我们传递日期的话是传1~31的。传入0的话就是到前一个月的最后一天
    let days = new Date(cYear, cMonth, 0).getDate();

    // 获取当前月份第一天是周几 getMonth()
    let week = new Date(cYear, cMonth - 1, 1).getDay(); // 0(周日)-6(周六)

    // 创建一个空字符串
    let dateStr = '';
    // 先保存内容为空的li
    for (let i = 0; i < week; i++) {
      dateStr += '<li></li>';
    }
    // 当i与今天日期一致，且年份、月份都相同时，添加current类名
    for (let i = 1; i <= days; i++) {
      dateStr += (cYear === currentYear && cMonth === currentMonth && i === cDay) ? `<li class="current">${i}</li>` :
        `<li>${i}</li>`;
    }
    // 将拼接好的li插入到ul中
    document.querySelector('#date').innerHTML = dateStr;

    [...document.querySelector('#date').children].forEach((item, index) => {
      // 给内容不为空的li添加鼠标移入移出事件
      if (item.innerHTML !== '') {
        item.addEventListener('mouseover', () => {
          item.classList.add('hover');
        });
        item.addEventListener('mouseout', () => {
          [...document.querySelector('#date').children].forEach(item => item.classList.remove('hover'));
        });
      }
      // 将内容为空的li鼠标样式设为默认值
      if (item.innerHTML === '') item.style.cursor = 'default';
    });
  }

  /* 
    字符串截取方法：
    + 1.substring(startIndex, endIndex)   startIndex可以取到，endIndex取不到
    + 2.slice(startIndex, endIndex)       startIndex可以取到，endIndex取不到
    + 3.substr(startIndex, length)        startIndex为开始截取位置，length为截取长度
      - 注意：方法1 与 方法2 效果相同，使用方式也一样 
  */
</script>

</html>